package com.github.binarylei.curator.cluster;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.junit.Test;

/**
 * @author: leigang
 * @version: 2018-04-06
 */
public class ZkCuratorWatcher {

    private static final String CONNECT_ADDR = "127.0.0.1:2181";
    private static final int SEESION_OUTTIME = 5 * 1000;

    public ZkCuratorWatcher() {
        try {
            //1. 重试策略：初试时间为1s，重试10次
            ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 10);

            //2. 通过工厂创建连接
            CuratorFramework cf = CuratorFrameworkFactory.builder()
                    .connectString(CONNECT_ADDR)
                    .sessionTimeoutMs(SEESION_OUTTIME)
                    .retryPolicy(retryPolicy)
                    .build();

            //3. 开启连接
            cf.start();

            //4. 创建根节点
            if (cf.checkExists().forPath("/cluster") == null) {
                cf.create().withMode(CreateMode.PERSISTENT).forPath("/cluster", "cluster".getBytes());
            }

            //5. 建立一个 PathChildrenCache 缓存，第三个参数为是否接受节点数据内容，如果为 false 则不接受
            PathChildrenCache cache = new PathChildrenCache(cf, "/cluster", true);
            //6. 在初始化的时候就进行缓存监听
            cache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);

            cache.getListenable().addListener(new PathChildrenCacheListener() {
                // 监听子节点变量，新建、修改、删除
                @Override
                public void childEvent(CuratorFramework cf, PathChildrenCacheEvent event) throws Exception {
                    switch (event.getType()) {
                        case CHILD_ADDED:
                            System.out.println("CHILD_ADDED：" + event.getData().getPath());
                            break;
                        case CHILD_UPDATED:
                            System.out.println("CHILD_UPDATED：" + event.getData().getPath());
                            break;
                        case CHILD_REMOVED:
                            System.out.println("CHILD_REMOVED：" + event.getData().getPath());
                            break;
                        default:
                            break;
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
